import sys
import System
import System.Threading
import clr
import time
import threading
import thread
import Queue
import nadgradnja
import SocketServer
import random
import time
from System.Net import *
import pris
import asys
import sap
import ee3_gui
import parallel
import komunikacija
import skrgo

#nadgradnja
Racunalniki = ["PURKAT", "PURKAT2"]
try:
    hostname = Dns.GetHostName()
    print(hostname)
    if hostname not in Racunalniki:
         nadgradnja.nadgradi()
    else:
        print("Nadgradnja se za ta PC ne dela!")
except Exception as e:
    debug.TraceDbg("Nadgradnja ni uspela!", "%s" %(e.message.ToString()), "Warning")

clr.AddReferenceByPartialName("IronPython")
clr.AddReferenceByPartialName("PresentationCore")
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName("WindowsBase")
clr.AddReferenceByPartialName("IronPython")
clr.AddReferenceByPartialName("Microsoft.Scripting")
clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')



from System import Action, AppDomain, UnhandledExceptionEventHandler, Windows
from System.Collections import *
clr.AddReferenceByPartialName('MySql.Data')
from MySql.Data.MySqlClient import *
clr.AddReference('System.Data')
from System.Data.SqlClient import SqlConnection
from System.Threading import *
from System.Threading.Tasks import *
from System.Windows.Threading import *
from System.Text.RegularExpressions import *
clr.AddReference("SAP_dll")
from SAP_dll import *
from System.ComponentModel import BackgroundWorker
from System.Windows import Window
from napake import *
from System.Windows.Controls import *
from System.Drawing import *

ee3_gui.init()

# GLOBALNE SPREMENLJIVKE
ProcesneSerijske_SAP = ""
ProcesneSerijske_ASYS = ""


#################### T E S T ######################

skrgo.skrgo(1)
plosca = parallel.parallel("")
plosca.plosca_status = "INIT"
#ee3_gui.paralelno_environment("Ena;Dva;Tri")
komunikacija.socket()

#################### T E S T ######################

# Delovni nalogi, operaterji, operacije
pris.dopolni(obrazec.comboBox_operaterji, "SELECT [ID], [KONTROLOR], [IME], [DELSTEV] FROM [KAKOVOST].[dbo].[SEZKONTROLORJEV] WHERE [STATUS] = 0 OR [STATUS] = 1 ORDER BY [IME];", "{ID}\t{KONTROLOR} {IME}", "poizvedba za operaterji")
pris.dopolni(obrazec.comboBox_operacije, "SELECT [ATE], [ZNAK] FROM [KAKOVOST].[dbo].[SEZATE] ORDER BY [ID];", "{ZNAK}\t{ATE}", "poizvedba za operacijami")
asys.dopolni(obrazec.comboBox_izdelki, "SELECT DISTINCT `Program` FROM `sledljivost`.`asysaba04` ORDER BY `Program`;", "{Program}", "poizvedba za izdelki")

# na textBox_dummyprocesna: ce pride serijska ali procesna, se stvar preveri v SAPu in se ustrezno nastavi
def dummyprocesna_accepted():
        obrazec.comboBox_izdelki.SelectedItem = None
        if (Regex("P[0-9A-Z]{8}[A|B]").IsMatch(obrazec.textBox_dummyprocesna.Text)):    #Ce je v dummy vnesena procesna in se nalog ne najde, poskusimo se s spremembo zadnjega znaka (A ali B - stran TIVa)
            # ker podatkov za izdelek ni na SAPu (verjetno ni uparjen), podatke pridobimo iz ASYS masine (procesna)
            asys.izberi(obrazec.comboBox_izdelki, "SELECT `Program` FROM `sledljivost`.`asysaba04` WHERE `Procesna` = '%s'" %obrazec.textBox_dummyprocesna.Text, "{Program}", "Poizvedba za izdelkom")
            asys.izberi(obrazec.comboBox_delnalogi, "SELECT `DN` FROM `sledljivost`.`asysaba04` WHERE `Procesna` = '%s'" %obrazec.textBox_dummyprocesna.Text, "{DN}", "Poizvedba za DN")
            return
        else:
            sap.poizvedbaSAPnalog(obrazec.textBox_dummyprocesna.Text)
            
                


def dummyprocesna_changed(sender, args):
    if (args.Key.ToString() == "Return" or args.Key.ToString() == "Tab"):
        dummyprocesna_accepted()
obrazec.textBox_dummyprocesna.KeyDown += dummyprocesna_changed

# ko izberemo izdelek, se pripisejo delovni nalogi
def izdelek_changed(sender, args):
    obrazec.comboBox_delnalogi.SelectedItem = None
    obrazec.comboBox_delnalogi.ItemsSource = None
    if (obrazec.comboBox_izdelki.SelectedItem != None):
        asys.dopolni(obrazec.comboBox_delnalogi, "SELECT DISTINCT `DN` FROM `sledljivost`.`asysaba04` WHERE `Program` = '%s'" %obrazec.comboBox_izdelki.SelectedItem.ToString(), "{DN}", "poizvedba za nalogi")
obrazec.comboBox_izdelki.SelectionChanged += izdelek_changed


# ko izberemo delovni nalog, se dopolni matrika procesna-serijska
def dn_changed(sender, args):
    global ProcesneSerijske_SAP
    global ProcesneSerijske_ASYS
    ProcesneSerijske_SAP = ""
    ProcesneSerijske_ASYS = ""
    if (obrazec.comboBox_delnalogi.SelectedItem != None):
        sap.poizvedbaSAPprocesneserijske(ProcesneSerijske_SAP, obrazec.comboBox_delnalogi.SelectedItem)
        asys.seznam(ProcesneSerijske_ASYS, "SELECT DISTINCT Substring(Procesna,1,9) FROM `sledljivost`.`asysaba04` WHERE `DN` IN ('%s') AND `Rezultat` LIKE 'PASS%%';" %obrazec.comboBox_delnalogi.SelectedItem.ToString(), "{Substring(Procesna,1,9)}", "Poizvedujem za procesnimi")
        osvezi_kolicine()
obrazec.comboBox_delnalogi.SelectionChanged += dn_changed

def osvezi_kolicine():
    global ProcesneSerijske_SAP
    global ProcesneSerijske_ASYS
    try:
        stavek_pass = "SELECT COUNT(*) FROM (SELECT PROCESNA, MAX(DATUM) as MaxTime FROM KAKOVOST.dbo.SPREMNILISTIZDELKA WHERE OPERACIJA IN ('%s') AND NALOG IN ('%s') AND (REZULTAT = 0 OR REZULTAT = 2 OR REZULTAT = 5) GROUP BY PROCESNA) r INNER JOIN SPREMNILISTIZDELKA t ON t.PROCESNA = r.PROCESNA AND t.DATUM = r.MaxTime AND t.REZULTAT = 0" %(obrazec.comboBox_operacije.SelectedItem.ToString().Substring(0, obrazec.comboBox_operacije.SelectedItem.ToString().IndexOf('\t')), obrazec.comboBox_delnalogi.SelectedItem.ToString())
        stavek_fail = "SELECT COUNT(*) FROM (SELECT PROCESNA, MAX(DATUM) as MaxTime FROM KAKOVOST.dbo.SPREMNILISTIZDELKA WHERE OPERACIJA IN ('%s') AND NALOG IN ('%s') AND (REZULTAT = 0 OR REZULTAT = 2 OR REZULTAT = 5) GROUP BY PROCESNA) r INNER JOIN SPREMNILISTIZDELKA t ON t.PROCESNA = r.PROCESNA AND t.DATUM = r.MaxTime AND t.REZULTAT = 2" %(obrazec.comboBox_operacije.SelectedItem.ToString().Substring(0, obrazec.comboBox_operacije.SelectedItem.ToString().IndexOf('\t')), obrazec.comboBox_delnalogi.SelectedItem.ToString())        
        stavek_karantena = "SELECT COUNT(*) FROM (SELECT PROCESNA, MAX(DATUM) as MaxTime FROM KAKOVOST.dbo.SPREMNILISTIZDELKA WHERE OPERACIJA IN ('%s') AND NALOG IN ('%s') AND (REZULTAT = 0 OR REZULTAT = 2 OR REZULTAT = 5) GROUP BY PROCESNA) r INNER JOIN SPREMNILISTIZDELKA t ON t.PROCESNA = r.PROCESNA AND t.DATUM = r.MaxTime AND t.REZULTAT = 5" %(obrazec.comboBox_operacije.SelectedItem.ToString().Substring(0, obrazec.comboBox_operacije.SelectedItem.ToString().IndexOf('\t')), obrazec.comboBox_delnalogi.SelectedItem.ToString())        
        stavek_nalog = "SELECT STMODULOV FROM KAKOVOST.dbo.DELNALOGI WHERE DELNALOG IN ('%s')" %(obrazec.comboBox_delnalogi.SelectedItem.ToString())
        postavke = [ee3_gui.lb_nalog, ee3_gui.lb_pass, ee3_gui.lb_fail, ee3_gui.lb_out, ee3_gui.lb_todo]
        pris.kolicine(postavke, "SELECT (%s) as st, (%s) as pass, (%s) as fail, (%s) as karantena" %(stavek_nalog, stavek_pass, stavek_fail, stavek_karantena), "{st};{pass};{fail};{karantena}", "Poizvedba za kolicinami")
    except Exception as e:
        debug.TraceDbg("Ne morem osveziti kolicin !", e.message.ToString(), "Warning")

# glede na izdelek "zafila" pozicije in napake
def kosovnica_content():
    pris.dopolni(obrazec.comboBox_pozicije_napake, "SELECT [KAKOVOST].[dbo].[KOSOVNICE].[POZICIJA] FROM [KAKOVOST].[dbo].[KOSOVNICE], [KAKOVOST].[dbo].[SEZMATERIALOV] WHERE [KAKOVOST].[dbo].[KOSOVNICE].[KODA]=(SELECT [ID] FROM [KAKOVOST].[dbo].[SEZKOD] WHERE [KODA]='%s') AND [KAKOVOST].[dbo].[SEZMATERIALOV].[ID] = [KAKOVOST].[dbo].[KOSOVNICE].[MAT];" %obrazec.comboBox_izdelki.SelectedItem.ToString(), "{POZICIJA}", "Poizvedba za pozicijami")

# funkcija, ki se izvede ko zacnemo z obdelavo plosce
def ObdelajPlosco(procesna, serijska):
    global ProcesneSerijske_SAP
    global ProcesneSerijske_ASYS
    plosca.plosca_error = ""
    plosca.plosca_info = ""
    plosca.plosca_warning = ""
    plosca.plosca_ok = ""

    if (procesna != None):
        if (procesna not in ProcesneSerijske_ASYS):
            plosca.plosca_error += "Plosce %s ni v seznamu procesnih nalepk!\n" %procesna
            plosca.procesna = "ERR"
        else:
            plosca.procesna = procesna
        if (type(ProcesneSerijske_SAP) != str):
            if (procesna not in ProcesneSerijske_SAP[1]):
                plosca.plosca_warning += "Plosca %s ni uparjena v SAPu!\n" %procesna
                plosca.serijska = ""
            else:
                plosca.serijska = ProcesneSerijske_SAP[0][ProcesneSerijske_SAP[1].IndexOf(procesna)]

    if (serijska != None):
        print(type(ProcesneSerijske_SAP))
        print(ProcesneSerijske_SAP)
        if (type(ProcesneSerijske_SAP) != str):
            if (serijska not in ProcesneSerijske_SAP[0]):
                plosca.plosca_error += "Plosca %s ni uparjena v SAPu!\n" %procesna
                plosca.serijska = ""
            else:
                plosca.serijska = serijska
                plosca.procesna = ProcesneSerijske_SAP[1][ProcesneSerijske_SAP[0].IndexOf(serijska)]
            if (plosca.procesna not in ProcesneSerijske_ASYS):
                plosca.plosca_error += "Plosce %s ni v seznamu procesnih nalepk!\n" %procesna
        else:
            plosca.plosca_error += "Plosce %s ne morem obdelati, ker ni vparjena v SAPu!\n" %procesna



    plosca.prikazi_na_obrazcu()

    if (plosca.error == ""):
        ## INFO ali je bila plosca ze na testu!
        pris.stevilotestiranj_in_napake(plosca, obrazec.comboBox_operacije.SelectedItem.ToString().Substring(0, obrazec.comboBox_operacije.SelectedItem.ToString().IndexOf('\t')))
        plosca.zacetek_testa()
        plosca.plosca_status = "TESTING"
    else:
        plosca.plosca_status = "ERROR"
        plosca.pass_fail_napake(plosca.plosca_status)


# funkcija ki se klice, ko je na vhodu sprememba znaka
def keylogger_textchanged(sender, args):
    serial=Regex("Z[0-9A-Z]{3}[0-9]{5}[G|H]")
    proces=Regex("P[0-9A-Z]{3}[0-9]{5}")
    if (serial.IsMatch(debug.textBox_logging.Text)):
        serijskast = serial.Match(debug.textBox_logging.Text).Value
        debug.TraceDbg("Serijska se je ujela %s!" %serijskast, None, "Info")
        debug.textBox_logging.Clear()
        ObdelajPlosco(None, serijskast)
    if (proces.IsMatch(debug.textBox_logging.Text)):
        procesnast = proces.Match(debug.textBox_logging.Text).Value
        debug.TraceDbg("Procesna se je ujela %s!" %procesnast, None, "Info")
        debug.textBox_logging.Clear()
        ObdelajPlosco(procesnast, None)

# Zavihka zaizdelek in napake sta onemogocena dokler glava ni izpolnjena
def glava_changed(sender, args):
    osvezi_kolicine()
    ee3_gui.brisiznake()
    if (obrazec.comboBox_operaterji.SelectedItem != None and obrazec.comboBox_operacije.SelectedItem != None and obrazec.comboBox_izdelki.SelectedItem != None and obrazec.comboBox_delnalogi.SelectedItem != None):
        kosovnica_content()
        obrazec.tabItem3.IsEnabled = 0
        obrazec.tabItem2.IsEnabled = 1
        debug.textBox_logging.TextChanged += keylogger_textchanged
        debug.checkBox_keyhooker.IsChecked = True
    else:
        obrazec.tabItem3.IsEnabled = 0
        obrazec.tabItem2.IsEnabled = 0
        obrazec.comboBox_pozicije_napake.ItemsSource = None
        debug.textBox_logging.TextChanged -= keylogger_textchanged
        debug.checkBox_keyhooker.IsChecked = False

obrazec.comboBox_operaterji.SelectionChanged += glava_changed
obrazec.comboBox_operacije.SelectionChanged += glava_changed
obrazec.comboBox_izdelki.SelectionChanged += glava_changed
obrazec.comboBox_delnalogi.SelectionChanged += glava_changed
glava_changed(None, None)

# Pozicija pri napakah se je spremenila. Poizvedba za "ident" in "tip materiala"
def kosovnica_element_changed(sender, args):
    if (obrazec.comboBox_pozicije_napake.SelectedItem != None):
        pris.dopolni(obrazec.textBox_ident_napake, "SELECT [KAKOVOST].[dbo].[KOSOVNICE].[IDENT] FROM [KAKOVOST].[dbo].[KOSOVNICE], [KAKOVOST].[dbo].[SEZMATERIALOV] WHERE [KAKOVOST].[dbo].[KOSOVNICE].[KODA]=(SELECT [ID] FROM [KAKOVOST].[dbo].[SEZKOD] WHERE [KODA]='%s') AND [KAKOVOST].[dbo].[SEZMATERIALOV].[ID] = [KAKOVOST].[dbo].[KOSOVNICE].[MAT] AND [KAKOVOST].[dbo].[KOSOVNICE].[POZICIJA] = '%s';" %(obrazec.comboBox_izdelki.SelectedItem.ToString(), obrazec.comboBox_pozicije_napake.SelectedItem.ToString()), "{IDENT}", "Poizvedba za identom")
        pris.dopolni(obrazec.textBox_material_napake, "SELECT [MATERIAL] FROM [KAKOVOST].[dbo].[SEZMATERIALOV] WHERE ID=(SELECT [KAKOVOST].[dbo].[KOSOVNICE].[MAT] FROM [KAKOVOST].[dbo].[KOSOVNICE] WHERE [KAKOVOST].[dbo].[KOSOVNICE].[POZICIJA] = '%s' AND [KAKOVOST].[dbo].[KOSOVNICE].[KODA] = (SELECT [KAKOVOST].[dbo].[SEZKOD].[ID] FROM [KAKOVOST].[dbo].[SEZKOD] WHERE [KAKOVOST].[dbo].[SEZKOD].[KODA]='%s'));" %(obrazec.comboBox_pozicije_napake.SelectedItem.ToString(), obrazec.comboBox_izdelki.SelectedItem.ToString()), "{MATERIAL}", "Poizvedba za materialom")
        pris.dopolni(obrazec.comboBox_napake_napake, "SELECT [NAPAK], [OPIS] FROM [KAKOVOST].[dbo].[SEZNAPAKN] WHERE [KRAJ]=(SELECT [KAKOVOST].[dbo].[KOSOVNICE].[KRAJ] FROM [KAKOVOST].[dbo].[KOSOVNICE] WHERE [KAKOVOST].[dbo].[KOSOVNICE].[POZICIJA] = '%s' AND [KAKOVOST].[dbo].[KOSOVNICE].[KODA] = (SELECT [KAKOVOST].[dbo].[SEZKOD].[ID] FROM [KAKOVOST].[dbo].[SEZKOD] WHERE [KAKOVOST].[dbo].[SEZKOD].[KODA]='%s')) ORDER BY [NAPAK]; "%(obrazec.comboBox_pozicije_napake.SelectedItem.ToString(), obrazec.comboBox_izdelki.SelectedItem.ToString()), "{NAPAK}: {OPIS}", "Poizvedba za napakami")
    else:
        obrazec.textBox_ident_napake.Text = ''
        obrazec.textBox_material_napake.Text = ''
        obrazec.comboBox_napake_napake.ItemsSource = None

obrazec.button_vpisi.IsEnabled = 0
obrazec.comboBox_pozicije_napake.SelectionChanged += kosovnica_element_changed

def napaka_izbrana(sender, args):
    if (obrazec.comboBox_napake_napake.SelectedItem != None):
        obrazec.button_vpisi.IsEnabled = 1
    else:
        obrazec.button_vpisi.IsEnabled = 0
obrazec.comboBox_napake_napake.SelectionChanged += napaka_izbrana


# Pritisk na gumb PASS ali FAIL
def pass_fail_click(sender, args):
    if (sender.Content == "PASS"):
        insert_stavek = ("INSERT INTO SPREMNILISTIZDELKA (PROCESNA, SERIJSKA, NALOG, DATUM, OPERACIJA, OPERATER, REZULTAT, TEST, DURATION) VALUES ('%s', '%s', '%s', CURRENT_TIMESTAMP, '%s', %s, %s, '%s', %s); SELECT SCOPE_IDENTITY();"
                             %(plosca.procesna, plosca.serijska, obrazec.comboBox_delnalogi.SelectedItem.ToString(),
                               obrazec.comboBox_operacije.SelectedItem.ToString().Substring(0, obrazec.comboBox_operacije.SelectedItem.ToString().IndexOf('\t')), obrazec.comboBox_operaterji.SelectedItem.ToString().Substring(0, obrazec.comboBox_operaterji.SelectedItem.ToString().IndexOf('\t')),
                               0, plosca.komentar, plosca.counter.Content))
    if (sender.Content == "FAIL"):
        insert_stavek = ("INSERT INTO SPREMNILISTIZDELKA (PROCESNA, SERIJSKA, NALOG, DATUM, OPERACIJA, OPERATER, REZULTAT, TEST, DURATION) VALUES ('%s', '%s', '%s', CURRENT_TIMESTAMP, '%s', %s, %s, '%s', %s); SELECT SCOPE_IDENTITY();"
                             %(plosca.procesna, plosca.serijska, obrazec.comboBox_delnalogi.SelectedItem.ToString(),
                               obrazec.comboBox_operacije.SelectedItem.ToString().Substring(0, obrazec.comboBox_operacije.SelectedItem.ToString().IndexOf('\t')), obrazec.comboBox_operaterji.SelectedItem.ToString().Substring(0, obrazec.comboBox_operaterji.SelectedItem.ToString().IndexOf('\t')),
                               2, plosca.komentar, plosca.counter.Content))
    pris.vpisi(plosca, insert_stavek, sender.Content)
    plosca.konec_testa()
    plosca.plosca_status = sender.Content
    plosca.pass_fail_napake(plosca.plosca_status)
    osvezi_kolicine()

obrazec.button_green.Click += pass_fail_click
obrazec.button_red.Click += pass_fail_click

# Pritisk na Vpisi napako
def napaka_vpis(sender, args):
    ID_napake = obrazec.comboBox_napake_napake.Tag[obrazec.comboBox_napake_napake.SelectedIndex]
    insert_stavek = ("INSERT INTO SPREMNILISTNAPAK (PROCESNA, OPERACIJA, OPERATER, POZICIJA, NAPAKA, OPIS, ID_IZDELEK) VALUES ('%s', '%s', %s, '%s', %s, '%s', %s); SELECT SCOPE_IDENTITY();"
        %(plosca.procesna, obrazec.comboBox_operacije.SelectedItem.ToString().Substring(0, obrazec.comboBox_operacije.SelectedItem.ToString().IndexOf('\t')), obrazec.comboBox_operaterji.SelectedItem.ToString().Substring(0, obrazec.comboBox_operaterji.SelectedItem.ToString().IndexOf('\t')),
        obrazec.comboBox_pozicije_napake.SelectedItem.ToString(), ID_napake, "", plosca.id))
